/*	--*- c -*--
 * Copyright (C) 2016 Enrico Scholz <enrico.scholz@sigma-chemnitz.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef H_ENSC_BAYER_RGB_BAYER2RGB_H
#define H_ENSC_BAYER_RGB_BAYER2RGB_H

#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif
#if 0
}
#endif

struct image_info {
	unsigned int		bpp;
	unsigned int		w;
	unsigned int		h;
	size_t			stride;
	enum {
		BAYER_E_LITTLE,
		BAYER_E_BIG,
	}			endian;
};

struct image_in {
	struct image_info	info;
	void const		*data;
	enum {
		BAYER_GRBG,
		BAYER_RGGB,
		BAYER_BGGR,
		BAYER_GBRG
	}			type;
};

struct rgbx32_pixel {
	uint8_t			r;
	uint8_t			g;
	uint8_t			b;
	uint8_t			pad;
};

struct bgrx32_pixel {
	uint8_t			b;
	uint8_t			g;
	uint8_t			r;
	uint8_t			pad;
};

struct xrgb32_pixel {
	uint8_t			pad;
	uint8_t			r;
	uint8_t			g;
	uint8_t			b;
};

struct xbgr32_pixel {
	uint8_t			pad;
	uint8_t			b;
	uint8_t			g;
	uint8_t			r;
};

struct rgb16_pixel {
	uint8_t			r:5;
	uint8_t			g:6;
	uint8_t			b:5;
};

enum image_quality {
	QUALITY_ROUND_2,
	QUALITY_ROUND_4,
	QUALITY_NO_ACCEL,
};

struct image_out {
	struct image_info	info;
	void			*data;
	unsigned long		quality;
	void const		*border;

	enum {
		RGB_FMT_RGBx,
		RGB_FMT_BGRx,
		RGB_FMT_xRGB,
		RGB_FMT_xBGR,
		RGB_FMT_RGB16,
	}			type;
};

struct image_conversion_info {
	char const	*fn;
	unsigned long	flags;
	char const	*fallback_reason;
};

void bayer2rgb_convert(struct image_in const *input,
		       struct image_out const *output,
		       struct image_conversion_info *info);

void bayer2rgb_convert_dumb(struct image_in const *input,
			    struct image_out const *output,
			    struct image_conversion_info *info);

void bayer2rgb_convert_cc(struct image_in const *input,
			  struct image_out const *output,
			  struct image_conversion_info *info);

void bayer2rgb_convert_c_opt(struct image_in const *input,
			     struct image_out const *output,
			     struct image_conversion_info *info);

void bayer2rgb_convert_neon(struct image_in const *input,
			    struct image_out const *output,
			    struct image_conversion_info *info);

bool bayer2rgb_reduce_bpp(struct image_info *image,
			  void const *in, void *out, unsigned int out_bpp,
			  struct image_conversion_info *info);


bool bayer2rgb_reduce_bpp_cc(struct image_info *image,
			     void const *in, void *out, unsigned int out_bpp,
			     struct image_conversion_info *info);


#if 0
{
#endif
#ifdef __cplusplus
}
#endif

#endif	/* H_ENSC_BAYER_RGB_BAYER2RGB_H */
